/*
Copyright (C) 2014  Johan Degraeve

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/gpl.txt>.

*/

package helpdiabetesj2me;

import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemRegistry;
import javax.microedition.lcdui.*;
import javax.microedition.rms.InvalidRecordIDException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreFullException;
import javax.microedition.rms.RecordStoreNotFoundException;
import javax.microedition.rms.RecordStoreNotOpenException;

/**
 *
 * @author Johan
 */
public class FoodFile implements CommandListener {
   

     static final String[] str_appstrt = {"Applicatie wordt opgestart"};
     static final String[] str_afsl = {"Afsluiten"};
     static final String[] str_ja = {"Ja"};
     static final String[] str_nee = {"Nee"};
     static final String[] str_fdrs_wrg_vers = {"Voedingsmiddelenbestand op de GSM heeft een incorrecte versie of werd niet correct ingelezen bij de initiële start. Het bestand wordt opnieuw geïnitialiseerd."};
     static final String[] str_fdrs_wrg_vers3 = {"Daarna kunt U eventueel uw eigen versie herladen via Menu/Herladen."};
     static final String[] str_info = {"Info"};
     static final String[] str_reading_food_file = {"Installatie..."};
     static final String[] str_reload = {"De GSM bevat een oudere versie van het voedingsmiddelenbestand dan de versie op de applicatie. Wenst U de versie van de applicatie te herladen ?"};
     static final String[] str_text1 = {"Voedingsmiddelenbestand zal gecreëerd worden op basis van de inhoud van de nieuwe applicatie."};
     static final String[] str_choose = {"Kies"};
     static final String[] str_back = {"Terug"};
     static final String[] str_text3 = {"De GSM bevat een oudere versie van het voedingsmiddelenbestand dan de versie op de applicatie. U hebt gekozen om het voedingsmiddelenbestand van de applicatie te herladen."};
     static final String[] str_fdtable = {"Voedingsmiddelenbestand"};
     static final String[] str_read = {"wordt ingelezen."};
     static final String[] str_status = {"Status"};
     static final String[] str_appclose = {"De applicatie zal afgesloten worden. Daarna kunt U de applicatie herstarten en zal de nieuwe inhoud correct getoond worden."};
     static final String[] str_uinfo1 = {"Er is te weinig geheugen vrij om het nieuw voedingsmiddelenbestand in te lezen." };
     static final String[] str_uinfo2 = {"Slechts"};
     static final String[] str_uinfo3 = {"van de"};
     static final String[] str_uinfo4 = {"items werden succesvol ingelezen."};
     static final String[] str_uinfo5 = {""};
     static final String[] str_uinfo6 = {"Voedingsmiddelenbestand op GSM wordt verwijderd."};
     static final String[] str_waitscr = {"Gelieve te wachten. De voedingsmiddelentabel wordt ingelezen, dit kan enkele minuten duren."};
     static final String[] str_warning = {"Opgelet !"};
     static final String[] str_already_exists1 = {"De lijst met toegevoegde voedingsmiddelen is nog niet leeg."};
     static final String[] str_already_exists2 = {"Wilt U de lijst eerst leegmaken ?"};
     static final String[] str_already_exists3 = {"(U kunt deze vraag verbergen via de Instellingen)"};
     
    // statics related to the layout of the rs and foodfile
    static public String foodtablesource;// version of the  csv file , will also be used as paramter to store the version of the rs file,

    static final String foodfilename = "/foodfile/foodfile.csv";
    static final public int nrofrecstoskip = 2;//nr of records that are not fooditems - depends on chosen layout of the recordstore
    
    static final int maxstrlngth = 512;//maximum length of a line in the input file
    
    private Command backinshowcurrdir ;
    private Command exit ;
    private Command Openinshowcurrdir;
    private Command ja;
    private Command nee;
    
  
    /* special string denotes upper directory */
    private static final String UP_DIRECTORY = "..";

    /* special string that denotes upper directory accessible by this browser.
     * this virtual directory contains all roots.
     */
    private static final String MEGA_ROOT = "/";

    /* separator string as defined by FC specification */
    private static final String SEP_STR = "/";

    /* separator character as defined by FC specification */
    private static final char SEP = '/';
    private String currDirName;
    
    private Image dirIcon;
    private Image fileIcon;
    //private Image[] iconList;

    private Alert confirm;//added 12/06

    //variables to help me
    byte[] retrieved;
    Alert myalert;
    String userinfo;
    String timestampinjar;
    Gauge progressgauge;
    Form progressform;

    private FileConnection fc;
    private InputStream fis;
    
    // will be the thread that searches the foodfile rs for the records that matches the entered searchstring
    Thread search;

    //maximum amount of bytes that will be stored in one record  store
    static private final int maxrssize = 200000;

    //points to the last record id in each rs
    static private int lastrecordinfoodrs;
    private CommandListener cmdlistner;
    
    /* constructor will check if foodfile in persistent memory exists, 
     * then user will be prompted to open a file from his phone (using filebrowser)
     *
     * To support situations where I change the layout of the foodfile rms :
     * If foodfile in persistent memory exists then version will be checked and compared to version of this application
     * If needed foodfile in persistent memory will be deleted and user will be prompted to load new file from phone. 
     */
    public FoodFile()  throws Exception {

        fis = null;
        currDirName = MEGA_ROOT;
        
        TextBox startscr = new TextBox(HelpDiabetes.appname,str_appstrt[HelpDiabetes.languageIndex],1024,TextField.ANY | TextField.UNEDITABLE);
        HelpDiabetes.midlet.getDisplay().setCurrent(startscr);
        
        exit = new Command(str_afsl[HelpDiabetes.languageIndex], Command.EXIT, 0);
        
        lastrecordinfoodrs = 100000;
         
        ja = new Command(str_ja[HelpDiabetes.languageIndex],Command.ITEM,0);
        nee = new Command(str_nee[HelpDiabetes.languageIndex],Command.BACK,0);
    
        /* first check if foodfile exists in persistent memory */
        try
            {
              // if the RecordStore does not exist then it will not yet be created
              // if it doesn't exist then this method will throw recordstorenotfoundexception which will be caught later'
              // but first setting the userinfo.
              userinfo = str_text1[HelpDiabetes.languageIndex] + " ";
              HelpDiabetes.foodrs = RecordStore.openRecordStore("foodfile", false);
                         
              // read the first record which contains the version and compare against required version
              retrieved = new byte[HelpDiabetes.foodrs.getRecordSize(1)];
              retrieved = HelpDiabetes.foodrs.getRecord(1);
              
              foodtablesource = new String(retrieved);
              //now check if the version is different from "0". "0" means the database was not correctly initialised at previous startup.
              //In that case throw a RecordStoreNotFoundException and do as if the recordstore was not found
              if (foodtablesource.compareTo("0") == 0) {
                  //Recordstore has verison "0
                  //first set the userinfo to another value
                  userinfo = str_fdrs_wrg_vers[HelpDiabetes.languageIndex] + " ";
                  
                  //close and delete all foodfile recordstores that may be open or may exist
                  deletefoodfileRMS();
                  
                  throw new RecordStoreNotFoundException();
              }
              
              
                // open the foodfile in the jar and check the version of that file against the version of the recordstore (timestamp)
                
                InputStream fis = this.getClass().getResourceAsStream(foodfilename);
                timestampinjar = ReadStringFromFile(fis);
                fis.close();
                timestampinjar =  timestampinjar.substring(0,timestampinjar.indexOf(','));
                // read the timetamp in the recordstore
                retrieved = new byte[HelpDiabetes.foodrs.getRecordSize(2)];
                HelpDiabetes.foodrs.getRecord(2,retrieved,0);
                String timestampinrs = new String(retrieved);
                
                lastrecordinfoodrs = HelpDiabetes.foodrs.getNumRecords();
                       
                if (timestampinrs.compareTo(timestampinjar) < 0) {
                    //rs is older than foodfile in jar
                    myalert = new Alert(str_info[HelpDiabetes.languageIndex],str_reload[HelpDiabetes.languageIndex],null,AlertType.CONFIRMATION);
                    myalert.addCommand(ja);
                    myalert.addCommand(nee);
                    myalert.setCommandListener(this);
                    HelpDiabetes.midlet.getDisplay().setCurrent(myalert);
                } else {
                    // rs is younger than foodfile in jar
                    //we have the food record store and we can switch back to getitemfromuser
                    FinishFoodfileCreation();
                }
              
            }
         
        catch (RecordStoreNotFoundException e1) //exception thrown while opening rms named "foodfile"
        {
            // recordstore does not exist so it needs to be created

            HelpDiabetes.foodrs = null;
            
            userinfo = userinfo + str_fdrs_wrg_vers3[HelpDiabetes.languageIndex];
            Startgaugeandthread(true,null);
        }
        catch (InvalidRecordIDException e2) {
            (new ReportException()).Report("Error while reading first record in foodfile recordstore.",e2,true);
           
        }
        catch (Exception e)
        { 
            (new ReportException()).Report("Unexpected error while opening foodfile recordstore.",e,false);
            
        }
         
        
    }
    
    /**
     * Show file list in the current directory .
     */
    public void showCurrDir()  {
        Enumeration e;
        FileConnection currDir = null;

        List browser;

        //check if icons arae loaded
        if (dirIcon == null | fileIcon == null) {
            try {
                dirIcon = Image.createImage("/icons/dir.png");
            } catch (IOException e1) {
                dirIcon = null;
            }
            try {
                fileIcon = Image.createImage("/icons/file.png");
            } catch (IOException e2) {
                fileIcon = null;
            }
            //iconList = new Image[] { fileIcon, dirIcon };
        }

        if (Openinshowcurrdir == null) {
            Openinshowcurrdir = new Command(str_choose[HelpDiabetes.languageIndex],str_choose[HelpDiabetes.languageIndex], Command.ITEM, 0);
        }
        if (backinshowcurrdir == null) {
            backinshowcurrdir = new Command(str_back[HelpDiabetes.languageIndex],str_back[HelpDiabetes.languageIndex], Command.BACK, 0);
        }

        try {
            if (MEGA_ROOT.equals(currDirName)) {
                e = FileSystemRegistry.listRoots();
                browser = new List(currDirName, List.IMPLICIT);
            } else {

                currDir = (FileConnection)Connector.open("file://localhost/" + currDirName,Connector.READ);
                e = currDir.list();
                browser = new List(currDirName, List.IMPLICIT);
                // not root - draw UP_DIRECTORY
                browser.append(UP_DIRECTORY, dirIcon);
            }

            while (e.hasMoreElements()) {
                String fileName = (String)e.nextElement();

                if (fileName.charAt(fileName.length() - 1) == SEP) {
                    // This is directory
                    browser.append(fileName, dirIcon);
                } else {
                    // this is regular file
                    browser.append(fileName, fileIcon);
                }
            }

            browser.setSelectCommand(Openinshowcurrdir);
            browser.addCommand(backinshowcurrdir);
            browser.setCommandListener(this);
            if (currDir != null) {
                currDir.close();
            }

            // don't need to send current to curdisp.getCurrent() , already done in constructor of foodfile'
            HelpDiabetes.midlet.getDisplay().setCurrent(browser);

        } catch (IOException ioe) {
            (new ReportException()).Report("Exception in showcurrdir()",ioe,false);

        }
    }


     void traverseDirectory(String fileName) {
        /* In case of directory just change the current directory
         * and show it
         */
        if (currDirName.equals(MEGA_ROOT)) {
            if (fileName.equals(UP_DIRECTORY)) {
                // can not go up from MEGA_ROOT
                return;
            }

            currDirName = fileName;
        } else if (fileName.equals(UP_DIRECTORY)) {
            // Go up one directory
            int i = currDirName.lastIndexOf(SEP, currDirName.length() - 2);

            if (i != -1) {
                currDirName = currDirName.substring(0, i + 1);
            } else {
                currDirName = MEGA_ROOT;
            }
        } else {
            currDirName = currDirName + fileName;
        }

        showCurrDir();
    }

    
    public void commandAction(Command command, Displayable screen)
    {
        if (command == backinshowcurrdir) {
            // this will close and/or reset variables, and also switch back to main displayable
            FinishFoodfileCreation();
        } else if (command == Openinshowcurrdir) {
            List curr = (List)screen;
            final String currFile = curr.getString(curr.getSelectedIndex());
                    new Thread(new Runnable() {
                        public void run() {
                            if (currFile.endsWith(SEP_STR) || currFile.equals(UP_DIRECTORY)) {
                                traverseDirectory(currFile);
                            } else {
                                Startgaugeandthread(false,currFile);
                            }
                        }
                    }).start();

        } else if

                
                (command == ja) {//users agrees to reload foodfile from jar file because it has a newer timestamp
                    userinfo = str_text3[HelpDiabetes.languageIndex] + " ";
                    new Thread(new Runnable() {
                    public void run() {
                         Startgaugeandthread(true,null);
                        }
                    }).start(); 
        } else if (command == nee) {//users does not agree to reload foodfile from jar file because it has a newer timestamp
                // replace the timestamp in the second record - to avoid that user is being asked the same question each time
                timestampinjar = gettimestamp();
                retrieved = timestampinjar.getBytes();
                try {
                    HelpDiabetes.foodrs.setRecord(2,retrieved,0,retrieved.length);
                } catch (Exception ex) {
                    (new ReportException()).Report("Exception in CommandAction with command = " + str_nee[HelpDiabetes.languageIndex] + ".",ex,true);
                }
            FinishFoodfileCreation();
        } else if (command == exit){//an out of memory error has occurred in loadfoodfile - application will be closed.
            HelpDiabetes.midlet.exitMIDlet();
        }
    }

    // will delete the recordstore if it exists
    // creates a form with userinformation and gauge
    // in case foodfile from jarfile is loaded, user information needs to be set by caller in variable 'userinfo'
    // in case foodfile from gSM disk is loaded, userinfo will be set by this method.
    // will start a gauge that will show the status
    // 
    // loadfromjar = if true, then foodfile from jarfile needs to be loaded, in that case displayable can be null and will not be used
    // if loadfromjar = false, then foodfile from disk will be opened - filename must contain a valid file name , currdirname must be set to a valid directory on the phone
    private void Startgaugeandthread(boolean loadfromjar, String filename) {
        final boolean localloadfromjar = loadfromjar;
        if (!loadfromjar) {
            try {
                  fc = (FileConnection) Connector.open("file://localhost/" + currDirName + filename,Connector.READ);

            } catch (IOException ex) {
                   (new ReportException()).Report("Exception in Foodfile.Startgaugeandthread, while creating fc",new Exception(),true);ex.printStackTrace();
            }
            if (!fc.exists()) {
                (new ReportException()).Report("Exception in Foodfile.Startgaugeandthread, fc not existing",new Exception(),true);
            }
         userinfo = str_fdtable[HelpDiabetes.languageIndex] + " " + filename + " " + str_read[HelpDiabetes.languageIndex];
        }
        
        //close and delete the foodfile recordstore if it already exists
        deletefoodfileRMS();
        
        try {
        
        //close and delete also the rs with already selected items
            HelpDiabetes.getSelectedItemRs().closeRecordStore();
        } catch (Exception ex) {
            ;
        } 
        try {
            RecordStore.deleteRecordStore("selecteditems");
        } catch (RecordStoreException ex) {
            ;
        }
        HelpDiabetes.setSelectedItemsRsToNull();
        
       // open form and add gauge that wil display status of loading
       userinfo = "\n\n" + userinfo + "\n\n" + str_status[HelpDiabetes.languageIndex] + " :";
       progressgauge = new Gauge(userinfo,false,1000,0);
       progressform = new Form(str_reading_food_file[HelpDiabetes.languageIndex]);
       progressform.append(progressgauge);
       HelpDiabetes.midlet.getDisplay().setCurrent(progressform);
       // start thread that will load the file
       new Thread(new Runnable() {
       public void run() {  
                    if (!localloadfromjar) {
                        try {



                            fis = fc.openInputStream();

                        } catch (IOException ex) {
                            (new ReportException()).Report("Exception in Foodfile.Startgaugeandthread while opening fc,",new Exception(),true);
                        }
                    }
                    LoadFoodFile(fis);
            }
          }).start();        
     
    }
    
    //fis, the inputstream to be used, if fis is null then resourceasstream will be used
    void LoadFoodFile(InputStream fis)  {
        int currentrssize=0;
        // open the file in the application
        byte[] b;
        int length,chr;
        int nroflinesinsource = 0;
        String readline;
        int recid = 0;
        boolean success = false;
        boolean loadingjarres = false;
        int  status = 0;
        int currentsizeavailable=0;
        try {
                
                if (fis == null) {
                    fis = this.getClass().getResourceAsStream(foodfilename);
                    loadingjarres = true;
                } else {
                    loadingjarres = false;
                }
status=1;                
                //First read the timestamp, I'm not going to do anything with it'
                readline = ReadStringFromFile(fis);
status=11;
                //Now read the version of the csv file
                readline = ReadStringFromFile(fis);
status=12;
                foodtablesource = readline.substring(0,readline.indexOf(','));
status=13;
                // Now read the number of lines in the source file - this is to set my gauge
                readline = ReadStringFromFile(fis);
status=14;
                nroflinesinsource = Integer.parseInt(readline.substring(0,readline.indexOf(',')));
                // set the maximum range of the gauge to nroflinesinsource
                progressgauge.setMaxValue(nroflinesinsource);
status=15;
                //create the recordstore
                HelpDiabetes.foodrs = RecordStore.openRecordStore("foodfile",true);
status=16;
                // first I'm storing 0 as version of the rs, this to guarantee that if the record creation would be interrupted then
                // at next startup this will be detected.'
                // note that in later versions, I added a statement at the end of this method, which replaces "0" with the source of the food composition table
                readline = "0";
status=17;
                b = readline.getBytes();
status=18;
                recid = HelpDiabetes.foodrs.addRecord(b,0,b.length);
status=2;
                // store the timestamp as second line - using readline as variable to avoid having to create a new one - saving memory :)
                readline = gettimestamp();
                b = readline.getBytes();
                recid = HelpDiabetes.foodrs.addRecord(b,0,b.length);
                //start reading all the remaining lines from the foodfile
                b = new byte[maxstrlngth];
                length = 1;//start value needs to be > 1
                chr = 0;//start value needs to be different from -1
                currentrssize = 0 ;//
                currentsizeavailable = HelpDiabetes.foodrs.getSizeAvailable();
                //as long as end of file not reached continue
                //as long as line is read which contains characters continue
                //as long as number of stored bytes is less than maximum recordsize
status=3;                
                while ((chr != -1) && (length > 0) && (currentrssize < maxrssize) && (currentsizeavailable > 2000)){
status=4;                    
                    length = 0;
                    chr = fis.read();
status=41;                    
                    if (chr == ',') 
                       {break;}//chr = ; means the first empty line, that's where we stop'
                    while ((chr != -1) & (chr != '\n')) {
                        if (chr != '\r') {//this LF seems to be there each time before \n
                            b[length] = (byte)chr;
status=42;                                                
                            length++;
                        }
                        chr = fis.read();
status=43;                        
                    }
                    if (length > 0) {
                        //means we've successfully read a line which contains something
                        recid = HelpDiabetes.foodrs.addRecord(b,0,length);
status=44;                        
                        currentrssize = currentrssize + length;
                        currentsizeavailable = HelpDiabetes.foodrs.getSizeAvailable();
status=45;                        
                 progressgauge.setValue(recid-1);
                    }
                }
status=5;                
                lastrecordinfoodrs = HelpDiabetes.foodrs.getNumRecords();                

                //if necessary continue with the next rms. foodrs2
status=6;                                
                fis.close();
                
                //only now I'm finally setting the correct version'*/
                b = foodtablesource.getBytes();
                HelpDiabetes.foodrs.setRecord(1,b,0,b.length);
                success=true;
                FinishFoodfileCreation();
                
                //I noticed on SE that after having reloaded a foodfile, the recordid's do not point to the correct content' So i will close the app
                if (!loadingjarres) {
                    (new UserInfo()).ReportAndClose(str_appclose[HelpDiabetes.languageIndex]);
                }
        } 
        catch (RecordStoreFullException oue) {
            deletefoodfileRMS();
            exit = new Command(str_afsl[HelpDiabetes.languageIndex], Command.EXIT, 0);
            userinfo = str_uinfo1[HelpDiabetes.languageIndex] + " " + str_uinfo2[HelpDiabetes.languageIndex] + " " + (recid - 3) + " " + str_uinfo3[HelpDiabetes.languageIndex] + " " + nroflinesinsource + " " + str_uinfo4[HelpDiabetes.languageIndex] + "\n"
                            + "\n"
                            + str_uinfo5[HelpDiabetes.languageIndex];
            userinfo = userinfo + "\n\n" + str_uinfo6[HelpDiabetes.languageIndex];
                            
            myalert = new Alert(str_info[HelpDiabetes.languageIndex],userinfo,null,AlertType.CONFIRMATION);
                    myalert.setTimeout(Alert.FOREVER);
                    myalert.addCommand(exit);
                    myalert.setCommandListener(this);
                    HelpDiabetes.midlet.getDisplay().setCurrent(myalert);
        }
        catch (Exception e) {
            e.printStackTrace();
            (new ReportException()).Report("Exception in LoadFoodFile. Status = "  + status + ".  Foodtable removed. Please try again.",e,true);
        } finally {
            try { fis.close();} catch (IOException e) {;}
            //try { fc.close();} catch (IOException e) {;}
            if (!success) {// foodfile recordstore has not been successfully created, so close and delete
                  deletefoodfileRMS();
            }
        }
    }
    
    // method to read a string from the inputsream
    // the inputstream must be opened already
    // returns null if eof is reached
    String ReadStringFromFile(InputStream fis) {
       StringBuffer returnvalue  = new StringBuffer();
       int chr, i = 0;
        try {
            // Read until the end of the stream   
            chr = fis.read();
            while ((chr  != -1) & (chr != '\n')) {
               if (chr != '\r') returnvalue.append((char) chr);
               chr = fis.read();
            }
        } catch (IOException ex) {
            (new ReportException()).Report("Exception in ReadStringFromFile.",ex,true);
        }
        return returnvalue.toString();
    }
    
    //method to return timestamp in correctformat in string
    String gettimestamp() {
        
        String[] counter = {"00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());//this gives the GMT time in milliseconds
        StringBuffer sb = new StringBuffer();
        //start with yyyy
        sb.append(cal.get(Calendar.YEAR));
        //mm (month)
        sb.append(counter[cal.get(Calendar.MONTH)+1]);//MONTH starts counting at 0
        //dd
        sb.append(counter[cal.get(Calendar.DAY_OF_MONTH)]);
        //hh 
        sb.append(counter[cal.get(Calendar.HOUR_OF_DAY)]);
        //mm (minutes)
        sb.append(counter[cal.get(Calendar.MINUTE)]);
        //ss
        sb.append(counter[cal.get(Calendar.SECOND)]);
        
        return sb.toString();
    }

    public void FinishFoodfileCreation() {
        if (HelpDiabetes.foodrs != null) {
            //foodrs was successfully opened, search thread can be started
            
            try {
                GetItemFromUser.foodrssize = HelpDiabetes.foodrs.getNumRecords();
            } catch (RecordStoreNotOpenException ex) {
                (new ReportException()).Report("Exception in FinishFoodFileCreation",ex, true);
            }
            if (search == null) {
                search = new Thread(HelpDiabetes.getitemfromuser);
                search.setPriority(Thread.MAX_PRIORITY);
                search.start();
            }
        }
        
         retrieved=null;
         dirIcon = null;
         fileIcon = null;
         backinshowcurrdir = null;
         exit = null;
         Openinshowcurrdir = null;
         userinfo = null;
         timestampinjar = null;
         fis = null;
         ja = null;
         nee = null;
       progressform = null;
       progressgauge = null;
         fc = null;

      HelpDiabetes.midlet.getDisplay().setCurrent(HelpDiabetes.getitemfromuser);
      //added 12/06 to add an alert screen at startup, when there's already a list then user will be asked to delete it or not
      // first of all close HelpDiabetes.selitemsrs because this one may still be pointing to an open rs, namely in case the application launches after having gone to sleep
      if (HDProperties.askbeforedelete()) {
          try {

          //close and delete also the rs with already selected items
            HelpDiabetes.closeSelectedItemsRs();
          } catch (RecordStoreNotOpenException ex1) {
            ;
          } catch (Exception ex) {
            ;
          } finally {
              HelpDiabetes.setSelectedItemsRsToNull();
          }
          try {
              if (HelpDiabetes.getSelectedItemRs().getNumRecords() > 0) {

                  String toprint = str_already_exists1[HelpDiabetes.languageIndex] +// list already exist
                          "\n" +
                          str_already_exists2[HelpDiabetes.languageIndex];
                  if (!HDProperties.questionalreadyasked()) {//we're only going to ask the last question once
                      toprint =  toprint + "\n\n" +
                              str_already_exists3[HelpDiabetes.languageIndex];//(you can suppress this warning via configurations)
                      HDProperties.setquestionalreadyasked(true);
                  }
                  confirm = new Alert(
                          str_warning[HelpDiabetes.languageIndex],//alert title
                          toprint,
                          null,
                          AlertType.WARNING);
                  confirm.setTimeout(Alert.FOREVER);
                  ja = new Command(str_ja[HelpDiabetes.languageIndex],Command.OK,0);
                  nee = new Command(str_nee[HelpDiabetes.languageIndex],Command.BACK,0);
                  confirm.addCommand(ja);
                  confirm.addCommand(nee);
                  cmdlistner = new CommandListener() {
                      public void commandAction(Command command, Displayable displayable)  {
                          if ((command == ja) || (command == Alert.DISMISS_COMMAND))  {
                              //delete the List rs
                              //first close the rs
                              deleteselecteditemslist(0);
                          }
                          HelpDiabetes.midlet.getDisplay().setCurrent(HelpDiabetes.getitemfromuser);
                      }
                  };
                  confirm.setCommandListener(cmdlistner);
                  HelpDiabetes.midlet.getDisplay().setCurrent(confirm);
              }
          } catch (RecordStoreNotFoundException ex3) {
            //this happens if selitemsrs  doesn't exist, which since the update done dec 2014 will never be the case
          } catch (RecordStoreException ex) {
              (new ReportException()).Report("Exception in FoodItemList - while opening selecteditemrs",ex,false);
          }
      } else {
          //we're not deleting the list, actually it will be checked again later in HelpDiabetes.getSelectedItemRs, if they need to be delete or not.
      }
      //end of part added 12/06
    }
    
    //for each possible foodfile recordstore :
    // close it and catch recordstorenotopenexception
    // delete it and catch recordstoreexception
    static public void deletefoodfileRMS() {
        try {
            HelpDiabetes.foodrs.closeRecordStore();
        } catch (Exception ex1) {
            ;
        } 
        HelpDiabetes.foodrs = null;
        try {
            RecordStore.deleteRecordStore("foodfile");
        } catch (Exception ex1) {
            ;
        } 
    }
    
    //used to read a foodfile line from the appropriate recordstore.                        
    static public int getRecord(int recordId, byte[] buffer, int offset) throws RecordStoreException {
        return HelpDiabetes.foodrs.getRecord(recordId,buffer,offset);                
    }


    //deletes the selected item list
    //counter is there to allow some repeating of this method recursively
    // if an exception occurs while deleting the recordstore, then I'll simply retry maximu once
    //normally it should be called with counter = 0, but from internally it will be called with the value of counter
    static void deleteselecteditemslist (int counter) {
      try {
          HelpDiabetes.closeSelectedItemsRs();
      } catch (RecordStoreNotOpenException recex) {
      }catch (RecordStoreException recex) {
      } catch (Exception othrex) {
      } finally {
          HelpDiabetes.setSelectedItemsRsToNull();
      }
      try {
          RecordStore.deleteRecordStore("selecteditems");
      } catch (RecordStoreNotFoundException recex) {
      }catch (RecordStoreException recex) {
          if (counter < 2)
              deleteselecteditemslist(counter + 1);
      }
    }
}
